/*
Copyright 2020 Esri

Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of
the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

For additional information, contact:
Environmental Systems Research Institute, Inc.
Attn: Contracts Dept
380 New York Street
Redlands, California, USA 92373
email: contracts@esri.com
*/

    #include "pch.h"
    #include "i3s/i3s_enums.h"
    #include "utils/utl_serialize.h"
    #include <cstring>
    // --------------------------------------
    // file generated by test/scripts/enum_serialize.py 
    // WARNING: EDITS WILL BE LOST !!
    // --------------------------------------
    namespace i3slib {
    namespace i3s {
    // --------------------------------------
    template<class Item, class T >
    std::string       _enum_val_to_string(T code, const Item* items,  int count)
    {
      //iterate:
      for (int i = 0; i < count; ++i)
        if (items[i].first == code)
          return items[i].second;
      return std::string();
    }
    template<class Item, class T >
    bool            _find_by_string(const std::string& txt_utf8, const Item* items, int count, T* out)
    {
      for (int i = 0; i < count; ++i)
        if (std::strcmp(items[i].second, txt_utf8.c_str()) == 0)
        {
          *out = items[i].first;
          return true;
        }
      return false;
    }
    // --------------------------------------
    
    struct Helper_Alpha_mode
    {
      typedef Alpha_mode Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Alpha_mode::Opaque, "opaque"},
{Alpha_mode::Mask, "mask"},
{Alpha_mode::Blend, "blend"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Alpha_mode::Item Helper_Alpha_mode::c_known[Helper_Alpha_mode::c_entry_count];

    std::string     to_string(Alpha_mode enum_val)   {    return Helper_Alpha_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Alpha_mode* out)  { return Helper_Alpha_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Alpha_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Alpha_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Face_culling_mode
    {
      typedef Face_culling_mode Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Face_culling_mode::None, "none"},
{Face_culling_mode::Front, "front"},
{Face_culling_mode::Back, "back"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Face_culling_mode::Item Helper_Face_culling_mode::c_known[Helper_Face_culling_mode::c_entry_count];

    std::string     to_string(Face_culling_mode enum_val)   {    return Helper_Face_culling_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Face_culling_mode* out)  { return Helper_Face_culling_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Face_culling_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Face_culling_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Type
    {
      typedef Type Enum_t;
      static constexpr int c_key_count = 16;
      static constexpr int c_entry_count = 16;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Type::Int8, "Int8"},
{Type::UInt8, "UInt8"},
{Type::Int16, "Int16"},
{Type::UInt16, "UInt16"},
{Type::Int32, "Int32"},
{Type::UInt32, "UInt32"},
{Type::Oid32, "Oid32"},
{Type::Int64, "Int64"},
{Type::UInt64, "UInt64"},
{Type::Oid64, "Oid64"},
{Type::Float32, "Float32"},
{Type::Float64, "Float64"},
{Type::String_utf8, "String"},
{Type::Date_iso_8601, "Date"},
{Type::Global_id, "GlobalID"},
{Type::Guid, "GUID"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Type::Item Helper_Type::c_known[Helper_Type::c_entry_count];

    std::string     to_string(Type enum_val)   {    return Helper_Type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Type* out)  { return Helper_Type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Domain_type
    {
      typedef Domain_type Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Domain_type::CodedValue, "codedValue"},
{Domain_type::Range, "range"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Domain_type::Item Helper_Domain_type::c_known[Helper_Domain_type::c_entry_count];

    std::string     to_string(Domain_type enum_val)   {    return Helper_Domain_type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Domain_type* out)  { return Helper_Domain_type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Domain_type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Domain_type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Esri_field_type
    {
      typedef Esri_field_type Enum_t;
      static constexpr int c_key_count = 10;
      static constexpr int c_entry_count = 11;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Esri_field_type::Date, "esriFieldTypeDate"},
{Esri_field_type::Single, "esriFieldTypeSingle"},
{Esri_field_type::Double, "esriFieldTypeDouble"},
{Esri_field_type::Guid, "esriFieldTypeGUID"},
{Esri_field_type::Global_id, "esriFieldTypeGlobalID"},
{Esri_field_type::Integer, "esriFieldTypeInteger"},
{Esri_field_type::Oid, "esriFieldTypeOID"},
{Esri_field_type::Small_integer, "esriFieldTypeSmallInteger"},
{Esri_field_type::String, "esriFieldTypeString"},
{Esri_field_type::Xml, "esriFieldTypeXML"},
{Esri_field_type::Integer, "FieldTypeInteger"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Esri_field_type::Item Helper_Esri_field_type::c_known[Helper_Esri_field_type::c_entry_count];

    std::string     to_string(Esri_field_type enum_val)   {    return Helper_Esri_field_type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Esri_field_type* out)  { return Helper_Esri_field_type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Esri_field_type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Esri_field_type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Key_value_encoding_type
    {
      typedef Key_value_encoding_type Enum_t;
      static constexpr int c_key_count = 1;
      static constexpr int c_entry_count = 1;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Key_value_encoding_type::Separated_key_values, "SeparatedKeyValues"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Key_value_encoding_type::Item Helper_Key_value_encoding_type::c_known[Helper_Key_value_encoding_type::c_entry_count];

    std::string     to_string(Key_value_encoding_type enum_val)   {    return Helper_Key_value_encoding_type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Key_value_encoding_type* out)  { return Helper_Key_value_encoding_type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Key_value_encoding_type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Key_value_encoding_type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Legacy_topology
    {
      typedef Legacy_topology Enum_t;
      static constexpr int c_key_count = 1;
      static constexpr int c_entry_count = 1;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Legacy_topology::Per_attribute_array, "PerAttributeArray"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Legacy_topology::Item Helper_Legacy_topology::c_known[Helper_Legacy_topology::c_entry_count];

    std::string     to_string(Legacy_topology enum_val)   {    return Helper_Legacy_topology::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Legacy_topology* out)  { return Helper_Legacy_topology::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Legacy_topology& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Legacy_topology& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Vertex_attrib_ordering
    {
      typedef Vertex_attrib_ordering Enum_t;
      static constexpr int c_key_count = 5;
      static constexpr int c_entry_count = 5;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Vertex_attrib_ordering::Position, "position"},
{Vertex_attrib_ordering::Normal, "normal"},
{Vertex_attrib_ordering::Uv0, "uv0"},
{Vertex_attrib_ordering::Color, "color"},
{Vertex_attrib_ordering::Region, "region"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Vertex_attrib_ordering::Item Helper_Vertex_attrib_ordering::c_known[Helper_Vertex_attrib_ordering::c_entry_count];

    std::string     to_string(Vertex_attrib_ordering enum_val)   {    return Helper_Vertex_attrib_ordering::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Vertex_attrib_ordering* out)  { return Helper_Vertex_attrib_ordering::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Vertex_attrib_ordering& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Vertex_attrib_ordering& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Feature_attrib_ordering
    {
      typedef Feature_attrib_ordering Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Feature_attrib_ordering::Fid, "id"},
{Feature_attrib_ordering::Face_range, "faceRange"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Feature_attrib_ordering::Item Helper_Feature_attrib_ordering::c_known[Helper_Feature_attrib_ordering::c_entry_count];

    std::string     to_string(Feature_attrib_ordering enum_val)   {    return Helper_Feature_attrib_ordering::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Feature_attrib_ordering* out)  { return Helper_Feature_attrib_ordering::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Feature_attrib_ordering& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Feature_attrib_ordering& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Geometry_header_property
    {
      typedef Geometry_header_property Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Geometry_header_property::Vertex_count, "vertexCount"},
{Geometry_header_property::Feature_count, "featureCount"},
{Geometry_header_property::Feature_count, "faceCount"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Geometry_header_property::Item Helper_Geometry_header_property::c_known[Helper_Geometry_header_property::c_entry_count];

    std::string     to_string(Geometry_header_property enum_val)   {    return Helper_Geometry_header_property::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Geometry_header_property* out)  { return Helper_Geometry_header_property::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Geometry_header_property& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Geometry_header_property& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Mesh_topology
    {
      typedef Mesh_topology Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 4;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Mesh_topology::Triangles, "triangles"},
{Mesh_topology::Lines, "lines"},
{Mesh_topology::Points, "points"},
{Mesh_topology::Triangles, "triangle"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Mesh_topology::Item Helper_Mesh_topology::c_known[Helper_Mesh_topology::c_entry_count];

    std::string     to_string(Mesh_topology enum_val)   {    return Helper_Mesh_topology::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Mesh_topology* out)  { return Helper_Mesh_topology::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Mesh_topology& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Mesh_topology& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Encoding
    {
      typedef Encoding Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Encoding::None, "none"},
{Encoding::String_utf8, "string-utf8"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Encoding::Item Helper_Encoding::c_known[Helper_Encoding::c_entry_count];

    std::string     to_string(Encoding enum_val)   {    return Helper_Encoding::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Encoding* out)  { return Helper_Encoding::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Encoding& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Encoding& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Lod_metric_type
    {
      typedef Lod_metric_type Enum_t;
      static constexpr int c_key_count = 5;
      static constexpr int c_entry_count = 5;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Lod_metric_type::Max_screen_area, "maxScreenThresholdSQ"},
{Lod_metric_type::Max_screen_size, "maxScreenThreshold"},
{Lod_metric_type::Distance, "distanceRangeFromDefaultCamera"},
{Lod_metric_type::Effective_density, "density-threshold"},
{Lod_metric_type::Screen_space_relative, "screenSpaceRelative"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Lod_metric_type::Item Helper_Lod_metric_type::c_known[Helper_Lod_metric_type::c_entry_count];

    std::string     to_string(Lod_metric_type enum_val)   {    return Helper_Lod_metric_type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Lod_metric_type* out)  { return Helper_Lod_metric_type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Lod_metric_type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Lod_metric_type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Layer_type
    {
      typedef Layer_type Enum_t;
      static constexpr int c_key_count = 7;
      static constexpr int c_entry_count = 7;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Layer_type::Mesh_3d, "3DObject"},
{Layer_type::Mesh_IM, "IntegratedMesh"},
{Layer_type::Point, "Point"},
{Layer_type::Point_cloud, "PointCloud"},
{Layer_type::Building, "Building"},
{Layer_type::Voxel, "Voxel"},
{Layer_type::Group, "group"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Layer_type::Item Helper_Layer_type::c_known[Helper_Layer_type::c_entry_count];

    std::string     to_string(Layer_type enum_val)   {    return Helper_Layer_type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Layer_type* out)  { return Helper_Layer_type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Layer_type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Layer_type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_VB_Binding
    {
      typedef VB_Binding Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {VB_Binding::Per_vertex, "per-vertex"},
{VB_Binding::Per_uv_region, "per-uv-region"},
{VB_Binding::Per_feature, "per-feature"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_VB_Binding::Item Helper_VB_Binding::c_known[Helper_VB_Binding::c_entry_count];

    std::string     to_string(VB_Binding enum_val)   {    return Helper_VB_Binding::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, VB_Binding* out)  { return Helper_VB_Binding::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const VB_Binding& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, VB_Binding& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Texture_filtering_mode
    {
      typedef Texture_filtering_mode Enum_t;
      static constexpr int c_key_count = 6;
      static constexpr int c_entry_count = 6;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Texture_filtering_mode::Nearest, "nearest"},
{Texture_filtering_mode::Linear, "linear"},
{Texture_filtering_mode::Nearest_mipmap_nearest, "nearest-mipmap-nearest"},
{Texture_filtering_mode::Linear_mipmap_nearest, "linear-mipmap-nearest"},
{Texture_filtering_mode::Nearest_mipmap_linear, "nearest-mipmap-linear"},
{Texture_filtering_mode::Linear_mipmap_linear, "linear-mipmap-linear"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Texture_filtering_mode::Item Helper_Texture_filtering_mode::c_known[Helper_Texture_filtering_mode::c_entry_count];

    std::string     to_string(Texture_filtering_mode enum_val)   {    return Helper_Texture_filtering_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Texture_filtering_mode* out)  { return Helper_Texture_filtering_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Texture_filtering_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Texture_filtering_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Texture_wrap_mode
    {
      typedef Texture_wrap_mode Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Texture_wrap_mode::Clamp, "clamp"},
{Texture_wrap_mode::Repeat, "repeat"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Texture_wrap_mode::Item Helper_Texture_wrap_mode::c_known[Helper_Texture_wrap_mode::c_entry_count];

    std::string     to_string(Texture_wrap_mode enum_val)   {    return Helper_Texture_wrap_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Texture_wrap_mode* out)  { return Helper_Texture_wrap_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Texture_wrap_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Texture_wrap_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Normal_reference_frame
    {
      typedef Normal_reference_frame Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Normal_reference_frame::East_north_up, "east-north-up"},
{Normal_reference_frame::Earth_centered, "earth-centered"},
{Normal_reference_frame::Vertex_reference_frame, "vertex-reference-frame"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Normal_reference_frame::Item Helper_Normal_reference_frame::c_known[Helper_Normal_reference_frame::c_entry_count];

    std::string     to_string(Normal_reference_frame enum_val)   {    return Helper_Normal_reference_frame::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Normal_reference_frame* out)  { return Helper_Normal_reference_frame::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Normal_reference_frame& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Normal_reference_frame& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Compressed_mesh_attribute
    {
      typedef Compressed_mesh_attribute Enum_t;
      static constexpr int c_key_count = 7;
      static constexpr int c_entry_count = 7;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Compressed_mesh_attribute::Position, "position"},
{Compressed_mesh_attribute::Normal, "normal"},
{Compressed_mesh_attribute::Uv0, "uv0"},
{Compressed_mesh_attribute::Color, "color"},
{Compressed_mesh_attribute::Uv_region, "uv-region"},
{Compressed_mesh_attribute::Feature_index, "feature-index"},
{Compressed_mesh_attribute::Flag, "flag"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Compressed_mesh_attribute::Item Helper_Compressed_mesh_attribute::c_known[Helper_Compressed_mesh_attribute::c_entry_count];

    std::string     to_string(Compressed_mesh_attribute enum_val)   {    return Helper_Compressed_mesh_attribute::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Compressed_mesh_attribute* out)  { return Helper_Compressed_mesh_attribute::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Compressed_mesh_attribute& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Compressed_mesh_attribute& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Attrib_header_property
    {
      typedef Attrib_header_property Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Attrib_header_property::Count, "count"},
{Attrib_header_property::Attribute_values_byte_count, "attributeValuesByteCount"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Attrib_header_property::Item Helper_Attrib_header_property::c_known[Helper_Attrib_header_property::c_entry_count];

    std::string     to_string(Attrib_header_property enum_val)   {    return Helper_Attrib_header_property::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Attrib_header_property* out)  { return Helper_Attrib_header_property::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Attrib_header_property& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Attrib_header_property& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Attrib_ordering
    {
      typedef Attrib_ordering Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 4;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Attrib_ordering::Attribute_values, "attributeValues"},
{Attrib_ordering::Attribute_byte_counts, "attributeByteCounts"},
{Attrib_ordering::Object_ids, "ObjectIds"},
{Attrib_ordering::Object_ids, "objectIds"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Attrib_ordering::Item Helper_Attrib_ordering::c_known[Helper_Attrib_ordering::c_entry_count];

    std::string     to_string(Attrib_ordering enum_val)   {    return Helper_Attrib_ordering::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Attrib_ordering* out)  { return Helper_Attrib_ordering::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Attrib_ordering& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Attrib_ordering& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Compressed_geometry_format
    {
      typedef Compressed_geometry_format Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Compressed_geometry_format::Not_init, "Not_set"},
{Compressed_geometry_format::Draco, "draco"},
{Compressed_geometry_format::Lepcc, "lepcc"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Compressed_geometry_format::Item Helper_Compressed_geometry_format::c_known[Helper_Compressed_geometry_format::c_entry_count];

    std::string     to_string(Compressed_geometry_format enum_val)   {    return Helper_Compressed_geometry_format::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Compressed_geometry_format* out)  { return Helper_Compressed_geometry_format::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Compressed_geometry_format& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Compressed_geometry_format& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Legacy_image_channel
    {
      typedef Legacy_image_channel Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Legacy_image_channel::Rgba, "rgba"},
{Legacy_image_channel::Rgb, "rgb"},
{Legacy_image_channel::Rgb, ""}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Legacy_image_channel::Item Helper_Legacy_image_channel::c_known[Helper_Legacy_image_channel::c_entry_count];

    std::string     to_string(Legacy_image_channel enum_val)   {    return Helper_Legacy_image_channel::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Legacy_image_channel* out)  { return Helper_Legacy_image_channel::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Legacy_image_channel& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Legacy_image_channel& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Legacy_wrap_mode
    {
      typedef Legacy_wrap_mode Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Legacy_wrap_mode::None, "none"},
{Legacy_wrap_mode::Repeat, "repeat"},
{Legacy_wrap_mode::Mirror, "mirror"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Legacy_wrap_mode::Item Helper_Legacy_wrap_mode::c_known[Helper_Legacy_wrap_mode::c_entry_count];

    std::string     to_string(Legacy_wrap_mode enum_val)   {    return Helper_Legacy_wrap_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Legacy_wrap_mode* out)  { return Helper_Legacy_wrap_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Legacy_wrap_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Legacy_wrap_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Mime_image_format
    {
      typedef Mime_image_format Enum_t;
      static constexpr int c_key_count = 6;
      static constexpr int c_entry_count = 10;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Mime_image_format::Jpg, "image/jpeg"},
{Mime_image_format::Png, "image/png"},
{Mime_image_format::Dds, "image/vnd-ms.dds"},
{Mime_image_format::Ktx, "image/ktx"},
{Mime_image_format::Basis, "image/basis"},
{Mime_image_format::Ktx2, "image/ktx2"},
{Mime_image_format::Jpg, "data:image/jpeg"},
{Mime_image_format::Png, "data:image/png"},
{Mime_image_format::Dds, "data:image/vnd-ms.dds"},
{Mime_image_format::Ktx, "data:image/ktx"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Mime_image_format::Item Helper_Mime_image_format::c_known[Helper_Mime_image_format::c_entry_count];

    std::string     to_string(Mime_image_format enum_val)   {    return Helper_Mime_image_format::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Mime_image_format* out)  { return Helper_Mime_image_format::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Mime_image_format& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Mime_image_format& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Legacy_uv_set
    {
      typedef Legacy_uv_set Enum_t;
      static constexpr int c_key_count = 1;
      static constexpr int c_entry_count = 1;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Legacy_uv_set::Uv0, "uv0"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Legacy_uv_set::Item Helper_Legacy_uv_set::c_known[Helper_Legacy_uv_set::c_entry_count];

    std::string     to_string(Legacy_uv_set enum_val)   {    return Helper_Legacy_uv_set::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Legacy_uv_set* out)  { return Helper_Legacy_uv_set::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Legacy_uv_set& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Legacy_uv_set& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Value_encoding
    {
      typedef Value_encoding Enum_t;
      static constexpr int c_key_count = 1;
      static constexpr int c_entry_count = 1;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Value_encoding::Utf8, "UTF-8"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Value_encoding::Item Helper_Value_encoding::c_known[Helper_Value_encoding::c_entry_count];

    std::string     to_string(Value_encoding enum_val)   {    return Helper_Value_encoding::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Value_encoding* out)  { return Helper_Value_encoding::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Value_encoding& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Value_encoding& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Time_encoding
    {
      typedef Time_encoding Enum_t;
      static constexpr int c_key_count = 1;
      static constexpr int c_entry_count = 1;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Time_encoding::Ecma_iso_8601, "ECMA_ISO8601"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Time_encoding::Item Helper_Time_encoding::c_known[Helper_Time_encoding::c_entry_count];

    std::string     to_string(Time_encoding enum_val)   {    return Helper_Time_encoding::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Time_encoding* out)  { return Helper_Time_encoding::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Time_encoding& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Time_encoding& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Attribute_storage_info_encoding
    {
      typedef Attribute_storage_info_encoding Enum_t;
      static constexpr int c_key_count = 4;
      static constexpr int c_entry_count = 4;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Attribute_storage_info_encoding::Embedded_elevation, "embedded-elevation"},
{Attribute_storage_info_encoding::Lepcc_xyz, "lepcc-xyz"},
{Attribute_storage_info_encoding::Lepcc_rgb, "lepcc-rgb"},
{Attribute_storage_info_encoding::Lepcc_intensity, "lepcc-intensity"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Attribute_storage_info_encoding::Item Helper_Attribute_storage_info_encoding::c_known[Helper_Attribute_storage_info_encoding::c_entry_count];

    std::string     to_string(Attribute_storage_info_encoding enum_val)   {    return Helper_Attribute_storage_info_encoding::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Attribute_storage_info_encoding* out)  { return Helper_Attribute_storage_info_encoding::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Attribute_storage_info_encoding& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Attribute_storage_info_encoding& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Bsl_filter_mode
    {
      typedef Bsl_filter_mode Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Bsl_filter_mode::Solid, "solid"},
{Bsl_filter_mode::Wireframe, "wireFrame"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Bsl_filter_mode::Item Helper_Bsl_filter_mode::c_known[Helper_Bsl_filter_mode::c_entry_count];

    std::string     to_string(Bsl_filter_mode enum_val)   {    return Helper_Bsl_filter_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Bsl_filter_mode* out)  { return Helper_Bsl_filter_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Bsl_filter_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Bsl_filter_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Height_model
    {
      typedef Height_model Enum_t;
      static constexpr int c_key_count = 3;
      static constexpr int c_entry_count = 3;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Height_model::Gravity_related, "gravity_related_height"},
{Height_model::Ellipsoidal, "ellipsoidal"},
{Height_model::Orthometric, "orthometric"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Height_model::Item Helper_Height_model::c_known[Helper_Height_model::c_entry_count];

    std::string     to_string(Height_model enum_val)   {    return Helper_Height_model::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Height_model* out)  { return Helper_Height_model::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Height_model& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Height_model& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Height_unit
    {
      typedef Height_unit Enum_t;
      static constexpr int c_key_count = 21;
      static constexpr int c_entry_count = 39;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Height_unit::Meter, "meter"},
{Height_unit::Us_foot, "us-foot"},
{Height_unit::Foot, "foot"},
{Height_unit::Clarke_foot, "clarke-foot"},
{Height_unit::Clarke_yard, "clarke-yard"},
{Height_unit::Clarke_link, "clarke-link"},
{Height_unit::Sears_yard, "sears-yard"},
{Height_unit::Sears_foot, "sears-foot"},
{Height_unit::Sears_chain, "sears-chain"},
{Height_unit::Benoit_chain, "benoit-1895-b-chain"},
{Height_unit::Indian_yard, "indian-yard"},
{Height_unit::Indian_1937_yard, "indian-1937-yard"},
{Height_unit::Gold_coast_foot, "gold-coast-foot"},
{Height_unit::Sears_trunc_chain, "sears-1922-trunctuated-chain"},
{Height_unit::Us_inch, "us-inch"},
{Height_unit::Us_mile, "us-mile"},
{Height_unit::Us_yard, "us-yard"},
{Height_unit::Millimeter, "millimeter"},
{Height_unit::Decimeter, "decimeter"},
{Height_unit::Centimeter, "centimeter"},
{Height_unit::Kilometer, "kilometer"},
{Height_unit::Meter, "Meter"},
{Height_unit::Meter, "Meters"},
{Height_unit::Us_foot, "foot_us"},
{Height_unit::Clarke_foot, "foot_clarke"},
{Height_unit::Clarke_yard, "yard_clarke"},
{Height_unit::Clarke_link, "link_clarke"},
{Height_unit::Sears_yard, "yard_sears"},
{Height_unit::Sears_foot, "foot_sears"},
{Height_unit::Sears_chain, "chain_sears"},
{Height_unit::Benoit_chain, "chain_benoit_1895_b"},
{Height_unit::Indian_yard, "yard_indian"},
{Height_unit::Indian_1937_yard, "yard_indian_1937"},
{Height_unit::Gold_coast_foot, "foot_gold_coast"},
{Height_unit::Sears_trunc_chain, "chain_sears_1922_trunctuated"},
{Height_unit::Us_inch, "inch_us"},
{Height_unit::Us_inch, "inch"},
{Height_unit::Us_mile, "mile_us"},
{Height_unit::Us_yard, "yard_us"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Height_unit::Item Helper_Height_unit::c_known[Helper_Height_unit::c_entry_count];

    std::string     to_string(Height_unit enum_val)   {    return Helper_Height_unit::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Height_unit* out)  { return Helper_Height_unit::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Height_unit& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Height_unit& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Continuity
    {
      typedef Continuity Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Continuity::Continuous, "continuous"},
{Continuity::Discrete, "discrete"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Continuity::Item Helper_Continuity::c_known[Helper_Continuity::c_entry_count];

    std::string     to_string(Continuity enum_val)   {    return Helper_Continuity::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Continuity* out)  { return Helper_Continuity::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Continuity& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Continuity& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Base_quantity
    {
      typedef Base_quantity Enum_t;
      static constexpr int c_key_count = 4;
      static constexpr int c_entry_count = 4;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Base_quantity::Horizontal_coordinate, "horizontal-coordinate"},
{Base_quantity::Vertical_coordinate, "vertical-coordinate"},
{Base_quantity::Time, "time"},
{Base_quantity::None, "none"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Base_quantity::Item Helper_Base_quantity::c_known[Helper_Base_quantity::c_entry_count];

    std::string     to_string(Base_quantity enum_val)   {    return Helper_Base_quantity::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Base_quantity* out)  { return Helper_Base_quantity::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Base_quantity& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Base_quantity& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Pcsl_attribute_buffer_type
    {
      typedef Pcsl_attribute_buffer_type Enum_t;
      static constexpr int c_key_count = 12;
      static constexpr int c_entry_count = 12;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Pcsl_attribute_buffer_type::Elevation, "ELEVATION"},
{Pcsl_attribute_buffer_type::Intensity, "INTENSITY"},
{Pcsl_attribute_buffer_type::Color_rgb, "RGB"},
{Pcsl_attribute_buffer_type::Class_code, "CLASS_CODE"},
{Pcsl_attribute_buffer_type::Flags, "FLAGS"},
{Pcsl_attribute_buffer_type::Returns, "RETURNS"},
{Pcsl_attribute_buffer_type::Point_id, "POINTID"},
{Pcsl_attribute_buffer_type::User_data, "USER_DATA"},
{Pcsl_attribute_buffer_type::Point_source_id, "POINT_SRC_ID"},
{Pcsl_attribute_buffer_type::Gps_time, "GPS_TIME"},
{Pcsl_attribute_buffer_type::Scan_angle_rank, "SCAN_ANGLE"},
{Pcsl_attribute_buffer_type::Near_infrared, "NEAR_INFRARED"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Pcsl_attribute_buffer_type::Item Helper_Pcsl_attribute_buffer_type::c_known[Helper_Pcsl_attribute_buffer_type::c_entry_count];

    std::string     to_string(Pcsl_attribute_buffer_type enum_val)   {    return Helper_Pcsl_attribute_buffer_type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Pcsl_attribute_buffer_type* out)  { return Helper_Pcsl_attribute_buffer_type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Pcsl_attribute_buffer_type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Pcsl_attribute_buffer_type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Bounding_volume_type
    {
      typedef Bounding_volume_type Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Bounding_volume_type::Obb, "obb"},
{Bounding_volume_type::Mbs, "mbs"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Bounding_volume_type::Item Helper_Bounding_volume_type::c_known[Helper_Bounding_volume_type::c_entry_count];

    std::string     to_string(Bounding_volume_type enum_val)   {    return Helper_Bounding_volume_type::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Bounding_volume_type* out)  { return Helper_Bounding_volume_type::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Bounding_volume_type& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Bounding_volume_type& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Vxl_variable_semantic
    {
      typedef Vxl_variable_semantic Enum_t;
      static constexpr int c_key_count = 4;
      static constexpr int c_entry_count = 4;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Vxl_variable_semantic::Stc_hot_spot_results, "stc-hot-spot-results"},
{Vxl_variable_semantic::Stc_cluster_outlier_results, "stc-cluster-outlier-results"},
{Vxl_variable_semantic::Stc_estimated_bin, "stc-estimated-bin"},
{Vxl_variable_semantic::Generic_nearest_interpolated, "generic-nearest-interpolated"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Vxl_variable_semantic::Item Helper_Vxl_variable_semantic::c_known[Helper_Vxl_variable_semantic::c_entry_count];

    std::string     to_string(Vxl_variable_semantic enum_val)   {    return Helper_Vxl_variable_semantic::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Vxl_variable_semantic* out)  { return Helper_Vxl_variable_semantic::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Vxl_variable_semantic& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Vxl_variable_semantic& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Vertical_exag_mode
    {
      typedef Vertical_exag_mode Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Vertical_exag_mode::Scale_position, "scale-position"},
{Vertical_exag_mode::Scale_height, "scale-height"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Vertical_exag_mode::Item Helper_Vertical_exag_mode::c_known[Helper_Vertical_exag_mode::c_entry_count];

    std::string     to_string(Vertical_exag_mode enum_val)   {    return Helper_Vertical_exag_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Vertical_exag_mode* out)  { return Helper_Vertical_exag_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Vertical_exag_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Vertical_exag_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Rendering_quality
    {
      typedef Rendering_quality Enum_t;
      static constexpr int c_key_count = 4;
      static constexpr int c_entry_count = 4;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Rendering_quality::Low, "low"},
{Rendering_quality::Medium, "medium"},
{Rendering_quality::High, "high"},
{Rendering_quality::Custom, "custom"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Rendering_quality::Item Helper_Rendering_quality::c_known[Helper_Rendering_quality::c_entry_count];

    std::string     to_string(Rendering_quality enum_val)   {    return Helper_Rendering_quality::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Rendering_quality* out)  { return Helper_Rendering_quality::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Rendering_quality& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Rendering_quality& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Interpolation
    {
      typedef Interpolation Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Interpolation::Linear, "linear"},
{Interpolation::Nearest, "nearest"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Interpolation::Item Helper_Interpolation::c_known[Helper_Interpolation::c_entry_count];

    std::string     to_string(Interpolation enum_val)   {    return Helper_Interpolation::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Interpolation* out)  { return Helper_Interpolation::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Interpolation& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Interpolation& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Vxl_render_mode
    {
      typedef Vxl_render_mode Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Vxl_render_mode::Volume, "volume"},
{Vxl_render_mode::Surfaces, "surfaces"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Vxl_render_mode::Item Helper_Vxl_render_mode::c_known[Helper_Vxl_render_mode::c_entry_count];

    std::string     to_string(Vxl_render_mode enum_val)   {    return Helper_Vxl_render_mode::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Vxl_render_mode* out)  { return Helper_Vxl_render_mode::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Vxl_render_mode& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Vxl_render_mode& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Vxl_rw_stats_status
    {
      typedef Vxl_rw_stats_status Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Vxl_rw_stats_status::Partial, "partial"},
{Vxl_rw_stats_status::Final, "final"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Vxl_rw_stats_status::Item Helper_Vxl_rw_stats_status::c_known[Helper_Vxl_rw_stats_status::c_entry_count];

    std::string     to_string(Vxl_rw_stats_status enum_val)   {    return Helper_Vxl_rw_stats_status::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Vxl_rw_stats_status* out)  { return Helper_Vxl_rw_stats_status::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Vxl_rw_stats_status& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Vxl_rw_stats_status& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Priority
    {
      typedef Priority Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Priority::High, "High"},
{Priority::Low, "Low"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Priority::Item Helper_Priority::c_known[Helper_Priority::c_entry_count];

    std::string     to_string(Priority enum_val)   {    return Helper_Priority::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Priority* out)  { return Helper_Priority::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Priority& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Priority& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Semantic
    {
      typedef Semantic Enum_t;
      static constexpr int c_key_count = 2;
      static constexpr int c_entry_count = 2;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Semantic::None, "None"},
{Semantic::Labels, "Labels"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Semantic::Item Helper_Semantic::c_known[Helper_Semantic::c_entry_count];

    std::string     to_string(Semantic enum_val)   {    return Helper_Semantic::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Semantic* out)  { return Helper_Semantic::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Semantic& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Semantic& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    

    struct Helper_Capability
    {
      typedef Capability Enum_t;
      static constexpr int c_key_count = 4;
      static constexpr int c_entry_count = 4;
      typedef std::pair< Enum_t, const char* > Item;
      static constexpr Item c_known[c_entry_count] =
      {
          {Capability::View, "View"},
{Capability::Query, "Query"},
{Capability::Edit, "Edit"},
{Capability::Extract, "Extract"}
      };
      static constexpr bool is_linear = (int)c_known[c_key_count - 1].first == c_key_count - 1;

      static std::string     to_string(Enum_t what)
      {
        if (is_linear)
          return (uint32_t)what < c_key_count ? c_known[(uint32_t)what].second : std::string();
        else
          return _enum_val_to_string(what, c_known, c_key_count);
      };
      static bool            from_string(const std::string& txt_utf8, Enum_t* out)
      {
        return _find_by_string(txt_utf8, c_known, c_entry_count, out);
      }
    };
    
    /*static*/ constexpr Helper_Capability::Item Helper_Capability::c_known[Helper_Capability::c_entry_count];

    std::string     to_string(Capability enum_val)   {    return Helper_Capability::to_string(enum_val); }
    bool            from_string(const std::string& txt_utf8, Capability* out)  { return Helper_Capability::from_string(txt_utf8, out);} 

    utl::Archive_out& operator&(utl::Archive_out& ar, const Capability& me)
    {
      auto tmp = to_string(me);
      ar & tmp;
      return ar;
    }
    utl::Archive_in& operator&(utl::Archive_in& ar, Capability& me)
    {
      if (ar.has_parse_error()) return ar;
      std::string tmp;
      ar & tmp;
      if (!from_string(tmp, &me))
      {
          ar.report_parsing_error(utl::Json_parse_error::Error::Unknown_enum, tmp );
      }
      return ar;
    }
    
    }}//endof ::i3s
    